#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <ctime>
#include <unistd.h>

using namespace std;

namespace protrol
{
    const string Sep = "\r\n";
    // 我们把tcp中读到的报文，可能读到半个，也可能读到1个半等， TCP 粘报问题
    // 解决TCP的粘报问题(添加长度)
    // 传输新的报文
    string Encode(const string &json_ptr)
    {
        int json_len = json_ptr.size();
        string protol_str = to_string(json_len);
        protol_str += Sep;
        protol_str += json_ptr;
        protol_str += Sep;
        return protol_str;
    }
    //  可能遇见多种情况
    // "len"\r\n"{
    // "len"\r\n"{             }"
    // "len"\r\n"{             }"\r\n;
    // "len"\r\n"{             }"\r\n"len";
    // "len"\r\n"{             }"\r\n"len"\r\n"{             }";
    // "len"\r\n"{             }"\r\n"len"\r\n"{             }"\r\n
    string Decode(string &inbuffer) // 识别只有一种报文（解析）
    {
        auto pos = inbuffer.find(Sep);
        if (pos == std::string::npos)
            return std::string();
        std::string len_str = inbuffer.substr(0, pos);
        if (len_str.empty())
            return std::string();
        int packlen = std::stoi(len_str);

        int total = packlen + len_str.size() + 2 * Sep.size();
        if (inbuffer.size() < total)
            return std::string();

        std::string package = inbuffer.substr(pos + Sep.size(), packlen);
        inbuffer.erase(0, total);
        return package;
    }
    class Request
    {
    public:
        Request() {}
        Request(int x, int y, char oper) : _x(x), _y(y), _oper(oper)
        {
        }
        bool Serialization(string *out)
        {
            // 初始化
            Json ::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["oper"] = _oper;
            // 写入
            Json ::FastWriter writer;
            *out = writer.write(root);
            return true;
        }
        bool Deserialization(const string &in)
        {
            Json ::Value root;
            Json::Reader reader;
            bool res = reader.parse(in, root);
            if (!res)
            {
                return false;
            }

            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt(); // 转化为accsii
            return true;
        }

        int _x;
        int _y;
        char _oper;
    };
    class Response
    {
    public:
        Response()
        {
        }
        Response(int res, int code) : _res(res), _code(code)
        {
        }
        bool Serialization(string *out)
        {
            // 初始化
            Json ::Value root;
            root["res"] = _res;
            root["code"] = _code;
            // 写入
            Json ::FastWriter writer;
            *out = writer.write(root);
            return true;
        }
        bool Deserialization(const string &in)
        {
            Json ::Value root;
            Json::Reader reader;
            bool res = reader.parse(in, root);
            if (!res)
            {
                return false;
            }

            _res = root["res"].asInt();
            _code = root["code"].asInt();
            return true;
        }
        int _res;
        int _code; // 0.success,1./0
    };
    // 随机化数种子
    class Factory
    {
    public:
        Factory()
        {
            srand(time(nullptr) ^ getpid());
            opers = "+-*/%^&|";
        }
        shared_ptr<Request> BulidRequest()
        {
            int x = rand() % 10 + 1;
            usleep(x * 10);
            int y = rand() % 5;
            usleep(x * y * 5);
            char oper = opers[rand() % opers.size()];
            shared_ptr<Request> req = make_shared<Request>(x, y, oper);
            return req;
        }
        shared_ptr<Response> BuildResponse()
        {
            return make_shared<Response>();
        }
        ~Factory()
        {
        }

    private:
        string opers;
    };
}